package com.googlecode.jtoy.productorandconsumer;

import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;

public class PipedInputOutputStream {
	private PipedOutputStream pos;
	private PipedInputStream pis;

	private int i = 0;

	public PipedInputOutputStream() {
		try {
			pos = new PipedOutputStream();
			pis = new PipedInputStream(pos);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		new PipedInputOutputStream().start();
	}

	public void start() {
		new Productor("Productor").start();
		new Consumer("Consumer1").start();
		new Consumer("Consumer2").start();
	}

	class Productor extends Thread {
		public Productor(String name) {
			this.setName(name);
		}

		@Override
		public void run() {
			try {
				while (true) {
					try {
						Thread.sleep((long) (100 * Math.random()));
					} catch (InterruptedException e1) {
						e1.printStackTrace();
					}

					int product = ++i;
					System.out.println(this.getName() + ": ++++++++++++++++++++" + product);
					pos.write(i);
					pos.flush();
				}
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				try {
					pos.close();
					pis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	class Consumer extends Thread {
		public Consumer(String name) {
			this.setName(name);
		}

		@Override
		public void run() {
			try {
				Thread.sleep((long) (200 * Math.random()));
			} catch (InterruptedException e1) {
				e1.printStackTrace();
			}

			try {
				while (true) {
					int product = pis.read();
					System.out.println(this.getName() + ": --------------------" + product);
					pos.flush();
				}
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				try {
					pos.close();
					pis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

}
